// File generated from our OpenAPI spec by Stainless.

package com.metest.api.client

import com.metest.api.core.ClientOptions
import com.metest.api.core.getPackageVersion
import com.metest.api.services.async.PetServiceAsync
import com.metest.api.services.async.PetServiceAsyncImpl
import com.metest.api.services.async.RestServiceAsync
import com.metest.api.services.async.RestServiceAsyncImpl
import com.metest.api.services.async.StoreServiceAsync
import com.metest.api.services.async.StoreServiceAsyncImpl
import com.metest.api.services.async.UserServiceAsync
import com.metest.api.services.async.UserServiceAsyncImpl
import java.util.function.Consumer

class MetestClientAsyncImpl(private val clientOptions: ClientOptions) : MetestClientAsync {

    private val clientOptionsWithUserAgent =
        if (clientOptions.headers.names().contains("User-Agent")) clientOptions
        else
            clientOptions
                .toBuilder()
                .putHeader("User-Agent", "${javaClass.simpleName}/Java ${getPackageVersion()}")
                .build()

    // Pass the original clientOptions so that this client sets its own User-Agent.
    private val sync: MetestClient by lazy { MetestClientImpl(clientOptions) }

    private val withRawResponse: MetestClientAsync.WithRawResponse by lazy {
        WithRawResponseImpl(clientOptions)
    }

    private val user: UserServiceAsync by lazy { UserServiceAsyncImpl(clientOptionsWithUserAgent) }

    private val pet: PetServiceAsync by lazy { PetServiceAsyncImpl(clientOptionsWithUserAgent) }

    private val store: StoreServiceAsync by lazy {
        StoreServiceAsyncImpl(clientOptionsWithUserAgent)
    }

    private val rest: RestServiceAsync by lazy { RestServiceAsyncImpl(clientOptionsWithUserAgent) }

    override fun sync(): MetestClient = sync

    override fun withRawResponse(): MetestClientAsync.WithRawResponse = withRawResponse

    override fun withOptions(modifier: Consumer<ClientOptions.Builder>): MetestClientAsync =
        MetestClientAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build())

    override fun user(): UserServiceAsync = user

    override fun pet(): PetServiceAsync = pet

    override fun store(): StoreServiceAsync = store

    override fun rest(): RestServiceAsync = rest

    override fun close() = clientOptions.close()

    class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) :
        MetestClientAsync.WithRawResponse {

        private val user: UserServiceAsync.WithRawResponse by lazy {
            UserServiceAsyncImpl.WithRawResponseImpl(clientOptions)
        }

        private val pet: PetServiceAsync.WithRawResponse by lazy {
            PetServiceAsyncImpl.WithRawResponseImpl(clientOptions)
        }

        private val store: StoreServiceAsync.WithRawResponse by lazy {
            StoreServiceAsyncImpl.WithRawResponseImpl(clientOptions)
        }

        private val rest: RestServiceAsync.WithRawResponse by lazy {
            RestServiceAsyncImpl.WithRawResponseImpl(clientOptions)
        }

        override fun withOptions(
            modifier: Consumer<ClientOptions.Builder>
        ): MetestClientAsync.WithRawResponse =
            MetestClientAsyncImpl.WithRawResponseImpl(
                clientOptions.toBuilder().apply(modifier::accept).build()
            )

        override fun user(): UserServiceAsync.WithRawResponse = user

        override fun pet(): PetServiceAsync.WithRawResponse = pet

        override fun store(): StoreServiceAsync.WithRawResponse = store

        override fun rest(): RestServiceAsync.WithRawResponse = rest
    }
}
